package cn.iocoder.yudao.module.eval.controller.admin.monitoring;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.module.eval.controller.admin.monitoring.vo.*;
import cn.iocoder.yudao.module.eval.dal.dataobject.monitoring.EvalMonitoringDataDO;
import cn.iocoder.yudao.module.eval.dal.dataobject.monitoring.EvalAttendanceDO;
import cn.iocoder.yudao.module.eval.dal.dataobject.monitoring.EvalSupervisionRecordDO;
import cn.iocoder.yudao.module.eval.service.monitoring.EvalMonitoringService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;

@Tag(name = "管理后台 - 评价实施监控")
@RestController
@RequestMapping("/eval/monitoring")
@Validated
@Slf4j
public class EvalMonitoringController {

    @Resource
    private EvalMonitoringService monitoringService;

    // ==================== 考勤签到管理 ====================

    @PostMapping("/attendance/checkin")
    @Operation(summary = "考生签到")
    @PreAuthorize("@ss.hasPermission('eval:monitoring:attendance')")
    @ApiAccessLog(operateType = CREATE)
    public CommonResult<Boolean> checkinCandidate(@Valid @RequestBody EvalAttendanceCheckinReqVO checkinReqVO) {
        // 转换为正确的VO类型
        EvalCandidateCheckInReqVO checkInReqVO = new EvalCandidateCheckInReqVO();
        checkInReqVO.setPlanId(checkinReqVO.getPlanId());
        checkInReqVO.setCandidateId(checkinReqVO.getCandidateId());
        checkInReqVO.setSubjectId(checkinReqVO.getSubjectId());
        checkInReqVO.setCheckInMethod(checkinReqVO.getCheckinMethod());
        checkInReqVO.setCheckInLocation(checkinReqVO.getCheckinLocation());
        checkInReqVO.setRemarks(checkinReqVO.getRemarks());

        monitoringService.checkinCandidate(checkInReqVO);
        return success(true);
    }

    @PostMapping("/attendance/{attendanceId}/checkout")
    @Operation(summary = "考生签退")
    @Parameter(name = "attendanceId", description = "考勤ID", required = true)
    @PreAuthorize("@ss.hasPermission('eval:monitoring:attendance')")
    @ApiAccessLog(operateType = UPDATE)
    public CommonResult<Boolean> checkoutCandidate(@PathVariable("attendanceId") Long attendanceId) {
        monitoringService.checkoutCandidate(attendanceId);
        return success(true);
    }

    @GetMapping("/attendance/plan/{planId}")
    @Operation(summary = "查询考勤记录")
    @Parameter(name = "planId", description = "计划ID", required = true)
    @Parameter(name = "subjectId", description = "科目ID", required = false)
    @Parameter(name = "attendanceStatus", description = "考勤状态", required = false)
    @PreAuthorize("@ss.hasPermission('eval:monitoring:query')")
    public CommonResult<List<EvalAttendanceRespVO>> getAttendanceRecords(
            @PathVariable("planId") Long planId,
            @RequestParam(value = "subjectId", required = false) Long subjectId,
            @RequestParam(value = "attendanceStatus", required = false) Integer attendanceStatus) {
        List<EvalAttendanceRespVO> list = monitoringService.getAttendanceRecords(planId, subjectId, attendanceStatus);
        return success(list);
    }

    @GetMapping("/attendance/plan/{planId}/statistics")
    @Operation(summary = "考勤统计")
    @Parameter(name = "planId", description = "计划ID", required = true)
    @PreAuthorize("@ss.hasPermission('eval:monitoring:query')")
    public CommonResult<EvalAttendanceStatisticsRespVO> getAttendanceStatistics(@PathVariable("planId") Long planId) {
        EvalAttendanceStatisticsRespVO statistics = monitoringService.getAttendanceStatistics(planId);
        return success(statistics);
    }

    @PostMapping("/attendance/batch-checkin")
    @Operation(summary = "批量签到")
    @PreAuthorize("@ss.hasPermission('eval:monitoring:attendance')")
    @ApiAccessLog(operateType = CREATE)
    public CommonResult<Boolean> batchCheckinCandidates(@Valid @RequestBody EvalAttendanceBatchCheckinReqVO batchCheckinReqVO) {
        monitoringService.batchCheckinCandidates(batchCheckinReqVO);
        return success(true);
    }

    // ==================== 实时监控 ====================

    @GetMapping("/dashboard/plan/{planId}")
    @Operation(summary = "获取监控仪表盘数据")
    @Parameter(name = "planId", description = "计划ID", required = true)
    @PreAuthorize("@ss.hasPermission('eval:monitoring:query')")
    public CommonResult<EvalMonitoringDashboardRespVO> getMonitoringDashboard(@PathVariable("planId") Long planId) {
        EvalMonitoringDashboardRespVO dashboard = monitoringService.getMonitoringDashboard(planId);
        return success(dashboard);
    }

    @PostMapping("/data")
    @Operation(summary = "添加监控数据")
    @PreAuthorize("@ss.hasPermission('eval:monitoring:create')")
    @ApiAccessLog(operateType = CREATE)
    public CommonResult<Boolean> addMonitoringData(@Valid @RequestBody EvalMonitoringDataSaveReqVO saveReqVO) {
        monitoringService.addMonitoringData(saveReqVO);
        return success(true);
    }

    @GetMapping("/data/plan/{planId}")
    @Operation(summary = "查询监控记录")
    @Parameter(name = "planId", description = "计划ID", required = true)
    @Parameter(name = "monitorType", description = "监控类型", required = false)
    @Parameter(name = "startTime", description = "开始时间", required = false)
    @Parameter(name = "endTime", description = "结束时间", required = false)
    @PreAuthorize("@ss.hasPermission('eval:monitoring:query')")
    public CommonResult<List<EvalMonitoringDataHistoryRespVO>> getMonitoringData(
            @PathVariable("planId") Long planId,
            @RequestParam(value = "monitorType", required = false) String monitorType,
            @RequestParam(value = "startTime", required = false) String startTime,
            @RequestParam(value = "endTime", required = false) String endTime) {
        List<EvalMonitoringDataHistoryRespVO> list = monitoringService.getMonitoringData(planId, monitorType, startTime, endTime);
        return success(list);
    }

    @GetMapping("/alerts/plan/{planId}")
    @Operation(summary = "获取监控预警")
    @Parameter(name = "planId", description = "计划ID", required = true)
    @Parameter(name = "alertLevel", description = "预警级别", required = false)
    @PreAuthorize("@ss.hasPermission('eval:monitoring:query')")
    public CommonResult<List<EvalMonitoringAlertRespVO>> getMonitoringAlerts(
            @PathVariable("planId") Long planId,
            @RequestParam(value = "alertLevel", required = false) Integer alertLevel) {
        List<EvalMonitoringAlertRespVO> alerts = monitoringService.getMonitoringAlerts(planId, alertLevel);
        return success(alerts);
    }

    @PostMapping("/alerts/{alertId}/handle")
    @Operation(summary = "处理监控预警")
    @Parameter(name = "alertId", description = "预警ID", required = true)
    @PreAuthorize("@ss.hasPermission('eval:monitoring:handle')")
    @ApiAccessLog(operateType = UPDATE)
    public CommonResult<Boolean> handleMonitoringAlert(@PathVariable("alertId") Long alertId,
                                                       @Valid @RequestBody EvalMonitoringAlertHandleReqVO handleReqVO) {
        monitoringService.handleMonitoringAlert(alertId, handleReqVO);
        return success(true);
    }

    // ==================== 督导检查管理 ====================

    @PostMapping("/supervision")
    @Operation(summary = "创建督导检查记录")
    @PreAuthorize("@ss.hasPermission('eval:monitoring:supervision')")
    @ApiAccessLog(operateType = CREATE)
    public CommonResult<Long> createSupervisionRecord(@Valid @RequestBody EvalSupervisionRecordSaveReqVO saveReqVO) {
        return success(monitoringService.createSupervisionRecord(saveReqVO));
    }

    @PutMapping("/supervision/{recordId}")
    @Operation(summary = "更新督导检查记录")
    @Parameter(name = "recordId", description = "记录ID", required = true)
    @PreAuthorize("@ss.hasPermission('eval:monitoring:supervision')")
    @ApiAccessLog(operateType = UPDATE)
    public CommonResult<Boolean> updateSupervisionRecord(@PathVariable("recordId") Long recordId,
                                                         @Valid @RequestBody EvalSupervisionRecordSaveReqVO updateReqVO) {
        updateReqVO.setId(recordId);
        monitoringService.updateSupervisionRecord(updateReqVO);
        return success(true);
    }

    @GetMapping("/supervision/plan/{planId}")
    @Operation(summary = "查询督导检查记录")
    @Parameter(name = "planId", description = "计划ID", required = true)
    @Parameter(name = "supervisorId", description = "督导员ID", required = false)
    @PreAuthorize("@ss.hasPermission('eval:monitoring:query')")
    public CommonResult<List<EvalSupervisionRecordRespVO>> getSupervisionRecords(
            @PathVariable("planId") Long planId,
            @RequestParam(value = "supervisorId", required = false) Long supervisorId) {
        List<EvalSupervisionRecordRespVO> list = monitoringService.getSupervisionRecords(planId, supervisorId);
        return success(list);
    }

    @GetMapping("/supervision/{recordId}")
    @Operation(summary = "获取督导检查记录详情")
    @Parameter(name = "recordId", description = "记录ID", required = true)
    @PreAuthorize("@ss.hasPermission('eval:monitoring:query')")
    public CommonResult<EvalSupervisionRecordRespVO> getSupervisionRecord(@PathVariable("recordId") Long recordId) {
        EvalSupervisionRecordRespVO record = monitoringService.getSupervisionRecord(recordId);
        return success(record);
    }

    @PutMapping("/supervision/{recordId}/submit-report")
    @Operation(summary = "提交督导报告")
    @Parameter(name = "recordId", description = "记录ID", required = true)
    @PreAuthorize("@ss.hasPermission('eval:monitoring:supervision')")
    @ApiAccessLog(operateType = UPDATE)
    public CommonResult<Boolean> submitSupervisionReport(@PathVariable("recordId") Long recordId,
                                                         @Valid @RequestBody EvalSupervisionReportSubmitReqVO submitReqVO) {
        monitoringService.submitSupervisionReport(recordId, submitReqVO.getReportContent());
        return success(true);
    }

    @GetMapping("/supervision/plan/{planId}/statistics")
    @Operation(summary = "督导检查统计")
    @Parameter(name = "planId", description = "计划ID", required = true)
    @PreAuthorize("@ss.hasPermission('eval:monitoring:query')")
    public CommonResult<EvalSupervisionStatisticsRespVO> getSupervisionStatistics(@PathVariable("planId") Long planId) {
        EvalSupervisionStatisticsRespVO statistics = monitoringService.getSupervisionStatistics(planId);
        return success(statistics);
    }

    // ==================== 实时状态更新 ====================

    @PostMapping("/status/update")
    @Operation(summary = "更新实时状态")
    @PreAuthorize("@ss.hasPermission('eval:monitoring:status')")
    @ApiAccessLog(operateType = UPDATE)
    public CommonResult<Boolean> updateRealTimeStatus(@Valid @RequestBody EvalRealTimeStatusUpdateReqVO statusUpdateReqVO) {
        monitoringService.updateRealTimeStatus(statusUpdateReqVO);
        return success(true);
    }

    @GetMapping("/status/plan/{planId}")
    @Operation(summary = "获取计划实时状态")
    @Parameter(name = "planId", description = "计划ID", required = true)
    @PreAuthorize("@ss.hasPermission('eval:monitoring:query')")
    public CommonResult<EvalPlanRealTimeStatusRespVO> getPlanRealTimeStatus(@PathVariable("planId") Long planId) {
        EvalPlanRealTimeStatusRespVO status = monitoringService.getPlanRealTimeStatus(planId);
        return success(status);
    }

    @GetMapping("/progress/plan/{planId}")
    @Operation(summary = "获取评价进度")
    @Parameter(name = "planId", description = "计划ID", required = true)
    @PreAuthorize("@ss.hasPermission('eval:monitoring:query')")
    public CommonResult<EvalProgressRespVO> getEvaluationProgress(@PathVariable("planId") Long planId) {
        EvalEvaluationProgressRespVO evaluationProgress = monitoringService.getEvaluationProgress(planId);
        // 转换为EvalProgressRespVO
        EvalProgressRespVO progress = new EvalProgressRespVO();
        progress.setPlanId(evaluationProgress.getPlanId());
        progress.setPlanName(evaluationProgress.getPlanName());
        progress.setOverallProgress(evaluationProgress.getOverallProgress());
        progress.setStartTime(evaluationProgress.getStartTime());
        progress.setExpectedEndTime(evaluationProgress.getExpectedEndTime());
        progress.setActualProgress(evaluationProgress.getActualProgress());

        // 转换科目进度列表
        if (evaluationProgress.getSubjectProgresses() != null) {
            List<EvalProgressRespVO.SubjectProgress> convertedProgresses = evaluationProgress.getSubjectProgresses().stream()
                .map(source -> {
                    EvalProgressRespVO.SubjectProgress target = new EvalProgressRespVO.SubjectProgress();
                    target.setSubjectId(source.getSubjectId());
                    target.setSubjectName(source.getSubjectName());
                    target.setProgress(source.getProgress());
                    target.setStatus(source.getStatus());
                    target.setEvaluatedCount(source.getEvaluatedCount());
                    target.setTotalCount(source.getTotalCount());
                    return target;
                }).collect(java.util.stream.Collectors.toList());
            progress.setSubjectProgresses(convertedProgresses);
        }

        return success(progress);
    }

    // ==================== 异常处理 ====================

    @PostMapping("/exception")
    @Operation(summary = "上报异常情况")
    @PreAuthorize("@ss.hasPermission('eval:monitoring:exception')")
    @ApiAccessLog(operateType = CREATE)
    public CommonResult<Long> reportException(@Valid @RequestBody EvalExceptionReportReqVO exceptionReqVO) {
        return success(monitoringService.reportException(exceptionReqVO));
    }

    @GetMapping("/exception/plan/{planId}")
    @Operation(summary = "查询异常记录")
    @Parameter(name = "planId", description = "计划ID", required = true)
    @PreAuthorize("@ss.hasPermission('eval:monitoring:query')")
    public CommonResult<List<EvalExceptionRecordRespVO>> getExceptionRecords(@PathVariable("planId") Long planId) {
        List<EvalExceptionRecordRespVO> records = monitoringService.getExceptionRecords(planId);
        return success(records);
    }

    @PostMapping("/exception/{exceptionId}/handle")
    @Operation(summary = "处理异常情况")
    @Parameter(name = "exceptionId", description = "异常ID", required = true)
    @PreAuthorize("@ss.hasPermission('eval:monitoring:exception')")
    @ApiAccessLog(operateType = UPDATE)
    public CommonResult<Boolean> handleException(@PathVariable("exceptionId") Long exceptionId,
                                                 @Valid @RequestBody EvalExceptionHandleReqVO handleReqVO) {
        monitoringService.handleException(exceptionId, handleReqVO);
        return success(true);
    }

}
